package com.github.common.extend.demo.config.json.jaskson.enumerate;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.github.common.extend.demo.config.BaseEnum;
import com.github.common.extend.demo.config.json.BaseEnumSerialize;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;

/**
 * 实现{@link BaseEnumSerialize}的功能
 * @author X1993
 * @date 2022/10/24
 * @description
 */
public class BaseEnumPropertyJsonSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    private BaseEnumSerialize baseEnumSerializeAnnotation;

    private BeanProperty beanProperty;

    public BaseEnumPropertyJsonSerializer() {
    }

    public BaseEnumPropertyJsonSerializer(final BaseEnumSerialize baseEnumSerializeAnnotation, BeanProperty beanProperty) {
        this.baseEnumSerializeAnnotation = baseEnumSerializeAnnotation;
        this.beanProperty = beanProperty;
    }

    @Override public void serialize(final Object s, final JsonGenerator jsonGenerator,
                                    final SerializerProvider serializerProvider) throws IOException
    {
        if (s != null && baseEnumSerializeAnnotation != null && beanProperty != null) {
            Class<? extends BaseEnum> baseEnumClass = baseEnumSerializeAnnotation.type();
            BaseEnum[] enumConstants = baseEnumClass.getEnumConstants();
            for (BaseEnum enumConstant : enumConstants) {
                if (s.equals(enumConstant.getCode())){
                    String descProperty = baseEnumSerializeAnnotation.descProperty();
                    String propertyName = beanProperty.getName();

                    if (StringUtils.isBlank(descProperty)){
                        descProperty = propertyName;
                    }

                    if (propertyName.equals(descProperty)){
                        jsonGenerator.writeObject(enumConstant.getDesc());
                        return;
                    }

                    jsonGenerator.writeObject(s);

                    //将描述写入指定的新属性
                    jsonGenerator.writeObjectField(descProperty ,enumConstant.getDesc());
                    return;
                }
            }
        }
        jsonGenerator.writeObject(s);
    }

    @Override public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
                                                        final BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty == null) {
            // 为空直接跳过
            return serializerProvider.findNullValueSerializer(beanProperty);
        }
        // 非 String 类直接跳过
        BaseEnumSerialize baseEnumSerialize = beanProperty.getAnnotation(BaseEnumSerialize.class);
        if (baseEnumSerialize == null) {
            baseEnumSerialize = beanProperty.getContextAnnotation(BaseEnumSerialize.class);
        }
        if (baseEnumSerialize != null) {
            return new BaseEnumPropertyJsonSerializer(baseEnumSerialize ,beanProperty);
        }
        throw new IllegalStateException();
    }

}
